package src.data;

import java.util.HashSet;
import java.util.List;
import java.util.Set;

import org.hibernate.Criteria;
import org.hibernate.FetchMode;
import org.hibernate.Query;
import org.hibernate.criterion.MatchMode;
import org.hibernate.criterion.Restrictions;
import src.domain.PostOffice;

public class PostOfficeDAO {


	private HibernateProvider provider;

	private static PostOfficeDAO instance = null;

	public static PostOfficeDAO getInstance() {
		if (instance == null)
			instance = new PostOfficeDAO();
		return instance;
	}

	private PostOfficeDAO() {
		this.provider = HibernateProvider.getInstance();

	}
	
	public PostOffice getByID(PostOffice postOffice){
		Criteria criteria = provider.getSession().createCriteria(PostOffice.class).add(Restrictions.like("id", postOffice.getId()));
		return (PostOffice) criteria.uniqueResult();	
	}
	
	public PostOffice getByName(PostOffice postOffice){
		Criteria criteria = provider.getSession().createCriteria(PostOffice.class).add(Restrictions.like("name", postOffice.getName(),MatchMode.EXACT));
		return (PostOffice) criteria.uniqueResult();	
	}
	
	@SuppressWarnings("unchecked")
	public Set<PostOffice> getAll() {

		Criteria criteria = provider.getSession().createCriteria(PostOffice.class).setFetchMode("trustOffices", FetchMode.JOIN);
		Set<PostOffice> set = new HashSet<PostOffice>();
		set.addAll(criteria.list());
		

		return set;

	}

	public void save(PostOffice postOffice) {

		// provider.getSession().save(provider.getSession().merge(user));
		provider.getSession().save(postOffice);
		

	}

	public void saveOrUpdate(PostOffice postOffice) {

		provider.getSession().saveOrUpdate(provider.getSession().merge(postOffice));
		

	}

	public void update(PostOffice postOffice) {

		provider.getSession().merge(postOffice);
		
	}

	public void delete(PostOffice postOffice) {
		provider.getSession().delete(postOffice);
		

	}
	
	@SuppressWarnings("unchecked")
	public Set<PostOffice> getPostOffices(PostOffice postOffice) {

		Criteria criteria = provider.getSession().createCriteria(PostOffice.class).add(Restrictions.like("name", postOffice.getName(),MatchMode.ANYWHERE)).setFetchMode("trustOffices", FetchMode.JOIN);
		Set<PostOffice> set = new HashSet<PostOffice>();
		set.addAll(criteria.list());
		return set;

	}
	
	
	@SuppressWarnings("unchecked")
	public Set<PostOffice> getAvailablePostOffices(PostOffice postOffice) {
		//TODO: change this dummy implementation
		
		//Query query = provider.getSession().createQuery("from p in class PostOffice where p not in (:trustOffices)");
		//query.setEntity("trustOffices",(Set<PostOffice>) postOffice.getTrustOffices());
		Query query = provider.getSession().createQuery("from p in class PostOffice");
		List<PostOffice> l=query.list();
		for(PostOffice p:postOffice.getTrustOffices())
			l.remove(p);
		l.remove(postOffice);
		
		
		
		
		Set<PostOffice> set = new HashSet<PostOffice>();
		set.addAll(l);
		//set.addAll(query.list());
		//query.list();
		
		/*Criteria criteria = provider.getSession().createCriteria(PostOffice.class).add(Restrictions.not(Restrictions.in("name",postOffice.getTrustOffices())));
		Set<PostOffice> set = new HashSet<PostOffice>();
		set.addAll(criteria.list());
		return set;*/
		
		return set;
	}
	
		
  
	
}
